#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;

// 节点结构体
struct NODE {
  int l, r, cnt, lz; // 左右边界、计数、懒惰标记
} tree[4 * N];

struct Seg {
  int L, R;
} seg[N];


// 懒惰更新
void lazy(int p, int v) {
  tree[p].lz += v; // 更新懒惰标记
  for (int i = 0; i < tree[p].cnt; i++) {
    tree[p].val[i] += v; // 更新值
  }
}

// 向下推送懒惰标记
void pushdown(int p) {
  lazy(p * 2, tree[p].lz);     // 更新左子树
  lazy(p * 2 + 1, tree[p].lz); // 更新右子树
  tree[p].lz = 0;              // 清空当前节点的懒惰标记
}

// 向上合并子树
void pushup(int p) {
  vector<int> tmp; // 临时存储合并结果
  int i = 0, j = 0;
  int cnt_l = tree[p * 2].cnt, cnt_r = tree[p * 2 + 1].cnt;
  vector<int> val_l = tree[p * 2].val, val_r = tree[p * 2 + 1].val;

  // 合并左右子树的值
  while (i < cnt_l && j < cnt_r) {
    tmp.emplace_back(val_l[i] > val_r[j] ? val_l[i++] : val_r[j++]);
  }
  while (i < cnt_l)
    tmp.emplace_back(val_l[i++]);
  while (j < cnt_r)
    tmp.emplace_back(val_r[j++]);

  tree[p].val.clear(); // 清空当前节点的值
  for (int i = 0; i < tree[p].cnt; i++) {
    tree[p].val.emplace_back(tmp[i]); // 更新当前节点的值
  }
}

// 建树
void build(int p, int l, int r) {
  tree[p].l = l, tree[p].r = r; // 设置节点的左右边界
  if (l == r) {
    tree[p].cnt = 1;                // 叶子节点
    tree[p].val.emplace_back(a[l]); // 存储值
    return;
  }
  int mid = l + ((r - l) >> 1);
  build(p * 2, l, mid);         // 构建左子树
  build(p * 2 + 1, mid + 1, r); // 构建右子树
  tree[p].cnt =
      min(tree[p * 2].cnt + tree[p * 2 + 1].cnt, 36); // 更新当前节点的计数
  pushup(p);                                          // 合并子树
}

// 更新区间
void update(int l, int r, int c, int p) {
  int s = tree[p].l, t = tree[p].r;
  if (l <= s && t <= r) {
    return lazy(p, c); // 完全覆盖，懒惰更新
  }
  if (tree[p].lz)
    pushdown(p); // 推送懒惰标记
  int mid = s + ((t - s) >> 1);
  if (l <= mid)
    update(l, r, c, p * 2); // 更新左子树
  if (r > mid)
    update(l, r, c, p * 2 + 1); // 更新右子树
  pushup(p);                    // 合并子树
}

// 合并结果
void merge(int p) {
  vector<int> tmp; // 临时存储合并结果
  int i = 0, j = 0, cnt = tree[p].cnt;
  vector<int> val = tree[p].val;

  // 合并当前节点的值和答案
  while (i < cnt && j < ans.size()) {
    tmp.emplace_back(val[i] > ans[j] ? val[i++] : ans[j++]);
  }
  while (i < cnt)
    tmp.emplace_back(val[i++]);
  while (j < ans.size())
    tmp.emplace_back(ans[j++]);

  ans.clear(); // 清空答案
  for (int i = 0; i < min((int)tmp.size(), 36); i++)
    ans.emplace_back(tmp[i]); // 更新答案
}

// 查询区间
void query(int l, int r, int p) {
  int s = tree[p].l, t = tree[p].r;
  if (l <= s && t <= r) {
    merge(p); // 完全覆盖，合并结果
    return;
  }
  if (tree[p].lz)
    pushdown(p); // 推送懒惰标记
  int mid = s + ((t - s) >> 1);
  if (l <= mid)
    query(l, r, p * 2); // 查询左子树
  if (r > mid)
    query(l, r, p * 2 + 1); // 查询右子树
  return;
}
  

void work() {
  int n;
  cin >> n;
  int minL = INT_MAX, maxR = INT_MIN;
  for (int i = 1; i <= n; i++) {
    cin >> seg[i].L >> seg[i].R;
    minL = min(minL, seg[i].L);
    maxR = max(maxR, seg[i].R);
  }

  build(1, minL, maxR); // 建树
  
  for (int i = 1; i <= n; i++) {
    int a, b;
    cin >> a >> b;
    update(a, b, 1, 1); // 更新区间
    
     
  } 
  for(int i = 1; i <= n; i++){
    query(seg[i].L, seg[i].R, 1); // 查询区间
    int res = 0;    // 存储结果
    
}
int main() {
  int T;
  while (T--) {
    work();
  }

  return 0; // 结束程序
}